#ifndef __GH615_HEADER_INFOS
#define __GH615_HEADER_INFOS

#include "HPort.h"

/**********************************************************************
 CONFIGURATION
**********************************************************************/
#define GHD_SPEED               CBR_57600
#define GHD_BITS                8
#define GHD_PARITY              NOPARITY
#define GHD_STOP                ONESTOPBIT
#define GHD_FLOW                FLOW_NONE

#define GHD_UPDATEWP_TMOUT      5000
#define GHD_WPLIST_TMOUT        2000
#define GHD_TRACKLIST_TMOUT     2000
#define GHD_DELTRACK_TMOUT      2000
#define GHD_SINGLECHAR_TMOUT    150

/**********************************************************************
 INFOs
**********************************************************************/
STRUCT( GH615_DeviceInfo )
  char       DeviceName[ 21 ];
  int        Version;             //Hi * 100 + Lo
  char       Firmware[ 17 ];
  char       User[ 16 ];
  BOOL       SexMale;
  int        Age;
  int        WeightPounds,
             WeightKilo,
             HeightInch,
             HeightCm;
  int        WpCount,
             TrCount;
  PRDateOnly Birth;
};

enum GH615Waypoints_t {
  ghwpDOT         = 0,
  ghwpHOUSE       = 1,
  ghwpTRIANGLE    = 2,
  ghwpTUNNEL      = 3,
  ghwpCROSS       = 4,
  ghwpFISH        = 5,
  ghwpLIGHT       = 6,
  ghwpCAR         = 7,
  ghwpCOMM        = 8,
  ghwpREDCROSS    = 9,
  ghwpTREE        = 10,
  ghwpBUS         = 11,
  ghwpCOPCAR      = 12,
  ghwpTREES       = 13,
  ghwpRESTAURANT  = 14,
  ghwpSEVEN       = 15,
  ghwpPARKING     = 16,
  ghwpREPAIRS     = 17,
  ghwpMAIL        = 18,
  ghwpDOLLAR      = 19,
  ghwpGOVOFFICE   = 20,
  ghwpCHURCH      = 21,
  ghwpGROCERY     = 22,
  ghwpHEART       = 23,
  ghwpBOOK        = 24,
  ghwpGAS         = 25,
  ghwpGRILL       = 26,
  ghwpLOOKOUT     = 27,
  ghwpFLAG        = 28,
  ghwpPLANE       = 29,
  ghwpBIRD        = 30,
  ghwpDAWN        = 31,
  ghwpRESTROOM    = 32,
  ghwpWTF         = 33,
  ghwpMANTARAY    = 34,
  ghwpINFORMATION = 35,
  ghwpBLANK       = 36,
  ghwpNONE        = -1,
};

STRUCT( GH615_Waypoint )
  char             Name[ 7 ];
  GH615Waypoints_t Type;
  double           Alt;
  double           Lat;
  double           Lon;
};

LOCALSTRUCT( GH615_Track )
  int        Id;
  PRTime     Time;
  PRTimeOnly Duration;
  double     Distance;
  int        Calories;
  double     TopSpeed;
  int        nPoints;
};

LOCALSTRUCT( GH615_TrackPoint )
  double Lat;
  double Lon;
  double Alt;
  double Speed;
  short  HeartRate;
  short  Interval;
  PRTime Time;
};
/**********************************************************************
 TYPES
**********************************************************************/
PRECLASS( GH615 );

#define GHD_MAX_WAYPOINTS       100
#define GHD_MAX_TRACKPOINTS     60000
#define GHD_MAXREPLY            0x10000

typedef MyRefArray<GH615_Waypoint>   GH615_Waypoints;
typedef MyRefArray<GH615_Track>      GH615_Tracks;
typedef MyRefArray<GH615_TrackPoint> GH615_TrackPoints;

typedef bool __fastcall (__closure *GH615_ProgressEvent)( GH615 *Sender, int Pc );

CLASS( GH615 )
   friend struct GH615_SaveDevice;
   HPort            port;
   int              nPort;
   BYTE             Reply[ GHD_MAXREPLY ];
   DWORD            nReply;

  private:
    BOOL ExecuteCmd( LPCVOID cmd, DWORD len, DWORD KnownRecvTimeout = INFINITE );
    BOOL ReadReply( DWORD Timeout );
    BOOL ReadReplyTm( DWORD tmOut );
    BOOL DoQueryTrack( int id );
    int  DoSetWaypoints( PGH615_Waypoint p, int cn );

  public:
    GH615( int Port, int CharReadTimeout = GHD_SINGLECHAR_TMOUT );

    BOOL             SetConnectParams( int bps,     // CBR_xx
                                       int bits,    // 5,6,7,8
                                       int parity,  // xxPARITY
                                       int sbits,   // xxSTOPBIT
                                       int flow,    // FLOW_xx
                                       int CharReadTimeout /*GHD_SINGLECHAR_TMOUT*/ );

    BOOL              OpenDevice( int port = -1 );
    BOOL              OpenDevice( CONSTSTR port = NULL );
    void              CloseDevice( void );
    BOOL              Opened( void ) const;

    DWORD             ReplyLen( void )  const;
    LPCBYTE           ReplyData( void ) const;

    BOOL              QueryInfo( void );
    BOOL              QueryWaypoints( void );
    BOOL              QueryTracks( void );
    BOOL              QueryTrack( int id );
    BOOL              DelAllTracks( DWORD tmOut = 5000 );
    BOOL              DelTrackData( int id );
    int               SetWaypoints( PGH615_Waypoint p, int cn );
    BOOL              TST( void );

  //Data
    GH615_DeviceInfo      DeviceInfo;
    GH615_Waypoints       Waypoints;
    GH615_Tracks          Tracks;
    GH615_TrackPoints     TrackPoints;

  //Events
    GH615_ProgressEvent   OnProgress;
};

#endif